#pragma once
#include <vector>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

extern const char* g_LastCommError;
#include "..\Global\globaldef.h"

//#define VTRY try
//#define VCATCH catch(std::string Exception){}
//#define VTHROW(message) throw std::string(message);
//#define VTHROW_INTERNALERROR(message) throw std::string("Internal Error: ").append(message);


#define COMM_PORT_I 27015

#define TIMEOUT (5*1000)
#define SERVER_TERMINATE_TIMEOUT (5*100)

typedef unsigned int uint;
class Server;


class Connection
{
public:

struct Packet
{
	struct Header
	{
		int packetID;
		UINT dataSize;
	} header;

	byte* pData;
	Packet();
	void ReleaseHeapData();
	~Packet();

};
private:
	std::vector<Connection::Packet> g_sendQue;
	std::vector<Connection::Packet> g_recieveQue;
	SOCKET m_socket;
	bool m_socketLive;
	int m_timeoutTimer;
	//int m_serverID;
	
	Server* m_pLocalServer;

	enum ThreadID
	{
		Connection::RECIEVE_THREAD = 0,
		Connection::SEND_THREAD = 1,
		THREAD_COUNT = 2
	};

	CRITICAL_SECTION criticalSections[Connection::THREAD_COUNT];
	HANDLE m_hThreads[Connection::THREAD_COUNT];

	static DWORD WINAPI RecieveThread(void* lpParam);
	static DWORD WINAPI SendThread(void* lpParam);
	
public:
	Connection(Server* pLocalServer = NULL);
	~Connection();
	bool Initalize(const char* hostname, bool isname = false);
	bool Initalize(SOCKET clientSocket);
	bool Release();
	bool IsConnected();

	void FlushQues();
	bool SendDataPacket(void* pData, unsigned int sizeInBytes, int packetID);
	bool GetDataPackets(std::vector<Connection::Packet> *pDataPacketList);
	bool HasRecievedPackets();
	
	void GetDebugString(char* buff, unsigned int buffLen);

	friend Server;
};
